home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / comm / term / term34Source.lha / termSerial.c < prev    next >
C/C++ Source or Header  |  1993-07-16  |  36KB  |  1,904 lines

  1. /*
  2. **    termSerial.c
  3. **
  4. **    Serial driver support routines
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* The quantum of bytes to be read from the serial port,
  13.      * to be fed to the terminal emulation monster. This is where
  14.      * two worlds collide; first there is the idea to process as
  15.      * much data as there is currently available for reasons
  16.      * of efficiency. Second there is a problem caused by the
  17.      * fact that terminal emulation may not be able to
  18.      * output text as fast as new data comes in. Terminal and
  19.      * serial input will be blocked until all data is processed,
  20.      * so the quantum should be pretty small to avoid unnecessary
  21.      * processing delays.
  22.      */
  23.  
  24.     /* Local copy of serial driver name and unit number. */
  25.  
  26. STATIC UBYTE    SerialDevice[40];
  27. STATIC LONG    UnitNumber = -1;
  28.  
  29.     /* SetFlags(struct IOExtSer *SomeRequest):
  30.      *
  31.      *    Set the contents of a serial device request according
  32.      *    to the current configuration settings.
  33.      */
  34.  
  35. VOID __regargs
  36. SetFlags(struct IOExtSer *SomeRequest)
  37. {
  38.         /* Remember new baud rate. */
  39.  
  40.     DTERate = Config -> SerialConfig -> BaudRate;
  41.  
  42.     SomeRequest -> io_Baud        = Config -> SerialConfig -> BaudRate;
  43.     SomeRequest -> io_BrkTime    = Config -> SerialConfig -> BreakLength;
  44.     SomeRequest -> io_ReadLen    = Config -> SerialConfig -> BitsPerChar;
  45.     SomeRequest -> io_WriteLen    = Config -> SerialConfig -> BitsPerChar;
  46.     SomeRequest -> io_StopBits    = Config -> SerialConfig -> StopBits;
  47.  
  48.     SomeRequest -> io_ExtFlags    &= ~(SEXTF_MSPON | SEXTF_MARK);
  49.     SomeRequest -> io_SerFlags    &= ~(SERF_PARTY_ON | SERF_PARTY_ODD | SERF_7WIRE | SERF_RAD_BOOGIE);
  50.  
  51.     switch(Config -> SerialConfig -> Parity)
  52.     {
  53.         case PARITY_EVEN:
  54.  
  55.             SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  56.             break;
  57.  
  58.         case PARITY_ODD:
  59.  
  60.             SomeRequest -> io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
  61.             break;
  62.  
  63.         case PARITY_MARK:
  64.  
  65.             SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  66.             SomeRequest -> io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
  67.             break;
  68.  
  69.         case PARITY_SPACE:
  70.  
  71.             SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  72.             SomeRequest -> io_ExtFlags |= SEXTF_MSPON;
  73.             break;
  74.     }
  75.  
  76.     if(Config -> SerialConfig -> HandshakingProtocol != HANDSHAKING_NONE)
  77.         SomeRequest -> io_SerFlags |= SERF_7WIRE;
  78.  
  79.     if(Config -> SerialConfig -> HighSpeed)
  80.         SomeRequest -> io_SerFlags |= SERF_RAD_BOOGIE;
  81.  
  82.     if(Config -> SerialConfig -> Shared)
  83.         SomeRequest -> io_SerFlags |= SERF_SHARED;
  84.  
  85.     SomeRequest -> io_SerFlags |= SERF_XDISABLED;
  86. }
  87.  
  88.     /* GetFlags(struct Configuration *Config,struct IOExtSer *SomeRequest):
  89.      *
  90.      *    Update configuration with serial settings.
  91.      */
  92.  
  93. VOID __regargs
  94. GetFlags(struct Configuration *Config,struct IOExtSer *SomeRequest)
  95. {
  96.     Config -> SerialConfig -> BaudRate    = SomeRequest -> io_Baud;
  97.     Config -> SerialConfig -> BreakLength    = SomeRequest -> io_BrkTime;
  98.     Config -> SerialConfig -> BitsPerChar    = SomeRequest -> io_ReadLen;
  99.     Config -> SerialConfig -> BitsPerChar    = SomeRequest -> io_WriteLen;
  100.     Config -> SerialConfig -> StopBits    = SomeRequest -> io_StopBits;
  101.  
  102.     if(SomeRequest -> io_SerFlags & SERF_PARTY_ON)
  103.     {
  104.         if(SomeRequest -> io_SerFlags & SERF_PARTY_ODD)
  105.             Config -> SerialConfig -> Parity = PARITY_ODD;
  106.         else
  107.         {
  108.             if(SomeRequest -> io_ExtFlags & SEXTF_MSPON)
  109.             {
  110.                 if(SomeRequest -> io_ExtFlags & SEXTF_MARK)
  111.                     Config -> SerialConfig -> Parity = PARITY_MARK;
  112.                 else
  113.                     Config -> SerialConfig -> Parity = PARITY_SPACE;
  114.             }
  115.         }
  116.     }
  117.     else
  118.         Config -> SerialConfig -> Parity = PARITY_NONE;
  119.  
  120.     if(SomeRequest -> io_SerFlags & SERF_7WIRE)
  121.         Config -> SerialConfig -> HandshakingProtocol = HANDSHAKING_RTSCTS;
  122.     else
  123.         Config -> SerialConfig -> HandshakingProtocol = HANDSHAKING_NONE;
  124.  
  125.     if(SomeRequest -> io_SerFlags & SERF_RAD_BOOGIE)
  126.         Config -> SerialConfig -> HighSpeed = TRUE;
  127.     else
  128.         Config -> SerialConfig -> HighSpeed = FALSE;
  129.  
  130.     if(SomeRequest -> io_SerFlags & SERF_SHARED)
  131.         Config -> SerialConfig -> Shared = TRUE;
  132.     else
  133.         Config -> SerialConfig -> Shared = FALSE;
  134.  
  135.     SomeRequest -> io_SerFlags |= SERF_XDISABLED;
  136. }
  137.  
  138.     /* CallMenu(STRPTR Name,ULONG Code):
  139.      *
  140.      *    Call a menu function either through the name of the corresponding
  141.      *    menu item or a menu number.
  142.      */
  143.  
  144. STATIC VOID __inline
  145. CallMenu(STRPTR Name,ULONG Code)
  146. {
  147.     WORD MenuNum = -1,Item = 0,Sub = 0,i;
  148.  
  149.         /* Are we to look for a name? */
  150.  
  151.     if(Name)
  152.     {
  153.         WORD Len = strlen(Name);
  154.  
  155.             /* Scan the menu list... */
  156.  
  157.         for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
  158.         {
  159.             switch(TermMenu[i] . nm_Type)
  160.             {
  161.                 case NM_TITLE:
  162.  
  163.                     MenuNum++;
  164.                     Item = Sub = 0;
  165.                     break;
  166.  
  167.                 case NM_ITEM:
  168.  
  169.                     Sub = 0;
  170.                     break;
  171.             }
  172.  
  173.                 /* Did we get a valid name string? */
  174.  
  175.             if(TermMenu[i] . nm_Label != NM_BARLABEL)
  176.             {
  177.                     /* Does the name match our template? */
  178.  
  179.                 if(!Strnicmp(TermMenu[i] . nm_Label,Name,Len))
  180.                 {
  181.                     struct MenuItem *MenuItem = ItemAddress(Menu,FULLMENUNUM(MenuNum,Item,Sub));
  182.  
  183.                     if(MenuItem)
  184.                         HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
  185.  
  186.                     break;
  187.                 }
  188.             }
  189.  
  190.             switch(TermMenu[i] . nm_Type)
  191.             {
  192.                 case NM_ITEM:
  193.  
  194.                     Item++;
  195.                     break;
  196.  
  197.                 case NM_SUB:
  198.  
  199.                     Sub++;
  200.                     break;
  201.             }
  202.         }
  203.     }
  204.     else
  205.     {
  206.         WORD    TheMenu    =  Code % 100,
  207.             TheItem    = (Code / 100) % 100,
  208.             TheSub    =  Code / 10000;
  209.  
  210.             /* Scan the menu list... */
  211.  
  212.         for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
  213.         {
  214.             switch(TermMenu[i] . nm_Type)
  215.             {
  216.                 case NM_TITLE:
  217.  
  218.                     MenuNum++;
  219.                     Item = Sub = 0;
  220.                     break;
  221.  
  222.                 case NM_ITEM:
  223.  
  224.                     Sub = 0;
  225.                     break;
  226.             }
  227.  
  228.                 /* Is it the menu number we want? */
  229.  
  230.             if(TheMenu == MenuNum && TheItem == Item && TheSub == Sub)
  231.             {
  232.                 if(TermMenu[i] . nm_Label != NM_BARLABEL)
  233.                 {
  234.                     struct MenuItem *MenuItem = ItemAddress(Menu,FULLMENUNUM(MenuNum,Item,Sub));
  235.  
  236.                     if(MenuItem)
  237.                         HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
  238.                 }
  239.  
  240.                 break;
  241.             }
  242.  
  243.             switch(TermMenu[i] . nm_Type)
  244.             {
  245.                 case NM_ITEM:
  246.  
  247.                     Item++;
  248.                     break;
  249.  
  250.                 case NM_SUB:
  251.  
  252.                     Sub++;
  253.                     break;
  254.             }
  255.         }
  256.     }
  257. }
  258.  
  259.     /* SerialCommand(STRPTR String):
  260.      *
  261.      *    Send a command string to the serial line and
  262.      *    interprete the control sequences.
  263.      */
  264.  
  265. VOID __regargs
  266. SerialCommand(STRPTR String)
  267. {
  268.     BYTE    (* __regargs SendLineLocal)(register STRPTR,register LONG);
  269.  
  270.     LONG    Count = 0,i,Len = strlen(String);
  271.  
  272.     BYTE    GotControl    = FALSE,
  273.         GotEscape    = FALSE,
  274.         OldStatus;
  275.  
  276.     SendLineLocal = SendLine;
  277.  
  278.         /* Scan the string. */
  279.  
  280.     for(i = 0 ; i < Len ; i++)
  281.     {
  282.             /* We are looking for plain characters
  283.              * and the control ('\') and escape
  284.              * ('^') characters.
  285.              */
  286.  
  287.         if(!GotControl && !GotEscape)
  288.         {
  289.                 /* Got a control character,
  290.                  * the next byte will probably be
  291.                  * a command sequence.
  292.                  */
  293.  
  294.             if(String[i] == '\\')
  295.             {
  296.                 GotControl = TRUE;
  297.                 continue;
  298.             }
  299.  
  300.                 /* Got an escape character,
  301.                  * the next byte will be some
  302.                  * kind of control character
  303.                  * (such as XON, XOF, bell, etc.).
  304.                  */
  305.  
  306.             if(String[i] == '^')
  307.             {
  308.                 GotEscape = TRUE;
  309.                 continue;
  310.             }
  311.  
  312.                 /* This tells us to wait another
  313.                  * second before continuing with
  314.                  * the scanning.
  315.                  */
  316.  
  317.             if(String[i] == '~')
  318.             {
  319.                 if(Count)
  320.                 {
  321.                     (*SendLineLocal)(SharedBuffer,Count);
  322.  
  323.                     Count = 0;
  324.                 }
  325.  
  326.                 WaitTime(0,MILLION / 2);
  327.  
  328.                 HandleSerial();
  329.  
  330.                 continue;
  331.             }
  332.  
  333.                 /* Stuff the character into the
  334.                  * buffer.
  335.                  */
  336.  
  337.             SharedBuffer[Count++] = String[i];
  338.         }
  339.         else
  340.         {
  341.                 /* Convert the character to a control
  342.                  * style character (^C, etc.).
  343.                  */
  344.  
  345.             if(GotEscape)
  346.             {
  347.                 if(ToUpper(String[i]) >= 'A' && ToUpper(String[i]) <= '_')
  348.                     SharedBuffer[Count++] = ToUpper(String[i]) - '@';
  349.                 else
  350.                     SharedBuffer[Count++] = String[i];
  351.  
  352.                 GotEscape = FALSE;
  353.             }
  354.  
  355.                 /* The next character represents a command. */
  356.  
  357.             if(GotControl)
  358.             {
  359.                 switch(ToUpper(String[i]))
  360.                 {
  361.                         /* Fall back to default send mode. */
  362.  
  363.                     case '0':
  364.  
  365.                         if(Count)
  366.                         {
  367.                             (*SendLineLocal)(SharedBuffer,Count);
  368.  
  369.                             Count = 0;
  370.                         }
  371.  
  372.                         SendLineLocal = SendLine;
  373.                         break;
  374.  
  375.                         /* Select `direct' send mode. */
  376.  
  377.                     case '1':
  378.  
  379.                         if(Count)
  380.                         {
  381.                             (*SendLineLocal)(SharedBuffer,Count);
  382.  
  383.                             Count = 0;
  384.                         }
  385.  
  386.                         SendLineLocal = SendLineSimple;
  387.                         break;
  388.  
  389.                         /* Select `echo' send mode. */
  390.  
  391.                     case '2':
  392.  
  393.                         if(Count)
  394.                         {
  395.                             (*SendLineLocal)(SharedBuffer,Count);
  396.  
  397.                             Count = 0;
  398.                         }
  399.  
  400.                         if(Config -> ClipConfig -> SendTimeout)
  401.                             SendLineLocal = SendLineEcho;
  402.                         else
  403.                             SendLineLocal = SendLineSimple;
  404.  
  405.                         break;
  406.  
  407.                         /* Select `any echo' send mode. */
  408.  
  409.                     case '3':
  410.  
  411.                         if(Count)
  412.                         {
  413.                             (*SendLineLocal)(SharedBuffer,Count);
  414.  
  415.                             Count = 0;
  416.                         }
  417.  
  418.                         if(Config -> ClipConfig -> SendTimeout)
  419.                             SendLineLocal = SendLineAnyEcho;
  420.                         else
  421.                             SendLineLocal = SendLineSimple;
  422.  
  423.                         break;
  424.  
  425.                         /* Select `prompt' send mode. */
  426.  
  427.                     case '4':
  428.  
  429.                         if(Count)
  430.                         {
  431.                             (*SendLineLocal)(SharedBuffer,Count);
  432.  
  433.                             Count = 0;
  434.                         }
  435.  
  436.                         if(Config -> ClipConfig -> SendTimeout)
  437.                             SendLineLocal = SendLinePrompt;
  438.                         else
  439.                             SendLineLocal = SendLineSimple;
  440.  
  441.                         break;
  442.  
  443.                         /* Select `delay' send mode. */
  444.  
  445.                     case '5':
  446.  
  447.                         if(Count)
  448.                         {
  449.                             (*SendLineLocal)(SharedBuffer,Count);
  450.  
  451.                             Count = 0;
  452.                         }
  453.  
  454.                         if(Config -> ClipConfig -> LineDelay || Config -> ClipConfig -> CharDelay)
  455.                             SendLineLocal = SendLineDelay;
  456.                         else
  457.                             SendLineLocal = SendLineSimple;
  458.  
  459.                         break;
  460.  
  461.                         /* Select `keyboard' send mode. */
  462.  
  463.                     case '6':
  464.  
  465.                         if(Count)
  466.                         {
  467.                             (*SendLineLocal)(SharedBuffer,Count);
  468.  
  469.                             Count = 0;
  470.                         }
  471.  
  472.                         SendLineLocal = SendLineKeyDelay;
  473.                         break;
  474.  
  475.                         /* Translate code. */
  476.  
  477.                     case '*':
  478.  
  479.                         i++;
  480.  
  481.                         while(i < Len && String[i] == ' ')
  482.                             i++;
  483.  
  484.                         if(i < Len)
  485.                         {
  486.                             UBYTE DummyBuffer[5],j = 0,Char;
  487.  
  488.                             if(String[i] >= '0' && String[i] <= '9')
  489.                             {
  490.                                 while(j < 3 && i < Len)
  491.                                 {
  492.                                     Char = String[i++];
  493.  
  494.                                     if(Char >= '0' && Char <= '9')
  495.                                         DummyBuffer[j++] = Char;
  496.                                     else
  497.                                     {
  498.                                         i--;
  499.  
  500.                                         break;
  501.                                     }
  502.                                 }
  503.                             }
  504.                             else
  505.                             {
  506.                                 while(j < 4 && i < Len)
  507.                                 {
  508.                                     Char = ToLower(String[i++]);
  509.  
  510.                                     if((Char >= '0' && Char <= '9') || (Char >= 'a' && Char <= 'z'))
  511.                                         DummyBuffer[j++] = Char;
  512.                                     else
  513.                                     {
  514.                                         i--;
  515.  
  516.                                         break;
  517.                                     }
  518.                                 }
  519.                             }
  520.  
  521.                             DummyBuffer[j] = 0;
  522.  
  523.                             SharedBuffer[Count++] = NameToCode(DummyBuffer);
  524.                         }
  525.  
  526.                         i--;
  527.  
  528.                         break;
  529.  
  530.                         /* Execute an AmigaDOS command. */
  531.  
  532.                     case 'D':
  533.  
  534.                         if(!InRexx)
  535.                         {
  536.                             if(!WeAreBlocking)
  537.                             {
  538.                                 BlockWindows();
  539.  
  540.                                 SendAmigaDOSCommand(&String[i + 1]);
  541.  
  542.                                 ReleaseWindows();
  543.                             }
  544.                             else
  545.                                 SendAmigaDOSCommand(&String[i + 1]);
  546.                         }
  547.  
  548.                         return;
  549.  
  550.                         /* Execute an ARexx command. */
  551.  
  552.                     case 'A':
  553. #ifdef USE_AREXX
  554.                         if(!InRexx)
  555.                         {
  556.                             if(!WeAreBlocking)
  557.                             {
  558.                                 BlockWindows();
  559.  
  560.                                 SendARexxCommand(&String[i + 1]);
  561.  
  562.                                 ReleaseWindows();
  563.                             }
  564.                             else
  565.                                 SendARexxCommand(&String[i + 1]);
  566.                         }
  567.  
  568. #endif    /* USE_AREXX */
  569.  
  570.                         return;
  571.  
  572.                         /* Add the control character ('\'). */
  573.  
  574.                     case '\\':
  575.  
  576.                         SharedBuffer[Count++] = '\\';
  577.                         break;
  578.  
  579.                         /* This is a backspace. */
  580.  
  581.                     case 'B':
  582.  
  583.                         SharedBuffer[Count++] = '\b';
  584.                         break;
  585.  
  586.                         /* This is a form feed. */
  587.  
  588.                     case 'F':
  589.  
  590.                         SharedBuffer[Count++] = '\f';
  591.                         break;
  592.  
  593.                         /* This is a line feed. */
  594.  
  595.                     case 'N':
  596.  
  597.                         SharedBuffer[Count++] = '\n';
  598.                         break;
  599.  
  600.                         /* Send the current password. */
  601.  
  602.                     case 'P':
  603.  
  604.                         if(Password[0])
  605.                         {
  606.                             if(Count)
  607.                             {
  608.                                 (*SendLineLocal)(SharedBuffer,Count);
  609.  
  610.                                 Count = 0;
  611.                             }
  612.  
  613.                             (*SendLineLocal)(Password,strlen(Password));
  614.                         }
  615.  
  616.                         break;
  617.  
  618.                         /* This is a carriage return. */
  619.  
  620.                     case 'R':
  621.  
  622.                         SharedBuffer[Count++] = '\r';
  623.                         break;
  624.  
  625.                         /* This is a tab. */
  626.  
  627.                     case 'T':
  628.  
  629.                         SharedBuffer[Count++] = '\t';
  630.                         break;
  631.  
  632.                         /* Send the current user name. */
  633.  
  634.                     case 'U':
  635.  
  636.                         if(UserName[0])
  637.                         {
  638.                             if(Count)
  639.                             {
  640.                                 (*SendLineLocal)(SharedBuffer,Count);
  641.  
  642.                                 Count = 0;
  643.                             }
  644.  
  645.                             (*SendLineLocal)(UserName,strlen(UserName));
  646.                         }
  647.  
  648.                         break;
  649.  
  650.                         /* Send a break across the serial line. */
  651.  
  652.                     case 'X':
  653.  
  654.                         if(Count)
  655.                         {
  656.                             (*SendLineLocal)(SharedBuffer,Count);
  657.  
  658.                             Count = 0;
  659.                         }
  660.  
  661.                         if(WriteRequest)
  662.                         {
  663.                             OldStatus = Status;
  664.  
  665.                             Status = STATUS_BREAKING;
  666.  
  667.                             WriteRequest -> IOSer . io_Command = SDCMD_BREAK;
  668.  
  669.                             DoIO(WriteRequest);
  670.  
  671.                             Status = OldStatus;
  672.                         }
  673.  
  674.                         break;
  675.  
  676.                         /* Feed the contents of the
  677.                          * clipboard into the input
  678.                          * stream.
  679.                          */
  680.  
  681.                     case 'I':
  682.  
  683.                         if(Count)
  684.                             (*SendLineLocal)(SharedBuffer,Count);
  685.  
  686.                         Count = LoadClip(SharedBuffer,256);
  687.  
  688.                         break;
  689.  
  690.                         /* Send a string to the clipboard. */
  691.  
  692.                     case 'G':
  693.  
  694.                         if(String[i + 1])
  695.                             SaveClip(&String[i + 1],strlen(&String[i + 1]));
  696.  
  697.                         return;
  698.  
  699.                         /* Send a string to the clipboard. */
  700.  
  701.                     case 'H':
  702.  
  703.                         if(String[i + 1])
  704.                             AddClip(&String[i + 1],strlen(&String[i + 1]));
  705.  
  706.                         return;
  707.  
  708.                         /* Produce the escape character. */
  709.  
  710.                     case 'E':
  711.  
  712.                         SharedBuffer[Count++] = ESC;
  713.                         break;
  714.  
  715.                         /* Call a menu item. */
  716.  
  717.                     case 'C':
  718.  
  719.                         i++;
  720.  
  721.                             /* Scan for a menu number or
  722.                              * a single quote...
  723.                              */
  724.  
  725.                         while(i < Len)
  726.                         {
  727.                             if(String[i] >= '0' && String[i] <= '9')
  728.                                 break;
  729.  
  730.                             if(String[i] == '\'')
  731.                                 break;
  732.  
  733.                             if(String[i] != ' ')
  734.                                 break;
  735.  
  736.                             i++;
  737.                         }
  738.  
  739.                         if(i < Len)
  740.                         {
  741.                             UBYTE DummyBuffer[256];
  742.  
  743.                                 /* Did we get a quote? */
  744.  
  745.                             if(String[i] == '\'')
  746.                             {
  747.                                 LONG Start = ++i;
  748.  
  749.                                 if(String[Start])
  750.                                 {
  751.                                     WORD Length;
  752.  
  753.                                     while(i < Len)
  754.                                     {
  755.                                         if(String[i] != '\'')
  756.                                             i++;
  757.                                         else
  758.                                             break;
  759.                                     }
  760.  
  761.                                     if(String[i] == '\'')
  762.                                         Length = i - Start;
  763.                                     else
  764.                                         Length = i - Start + 1;
  765.  
  766.                                     memcpy(DummyBuffer,&String[Start],Length);
  767.  
  768.                                     DummyBuffer[Length] = 0;
  769.  
  770.                                     CallMenu(DummyBuffer,0);
  771.                                 }
  772.                             }
  773.                             else
  774.                             {
  775.                                 if(String[i] >= '0' && String[i] <= '9')
  776.                                 {
  777.                                     LONG Start = i,Length;
  778.  
  779.                                     while(i < Len)
  780.                                     {
  781.                                         if(String[i] >= '0' && String[i] <= '9')
  782.                                             i++;
  783.                                         else
  784.                                             break;
  785.                                     }
  786.  
  787.                                     if(i == Start)
  788.                                         Length = 1;
  789.                                     else
  790.                                         Length = i - Start;
  791.  
  792.                                     memcpy(DummyBuffer,&String[Start],Length);
  793.  
  794.                                     DummyBuffer[Length] = 0;
  795.  
  796.                                     CallMenu(NULL,Atol(DummyBuffer));
  797.                                 }
  798.                             }
  799.                         }
  800.  
  801.                         break;
  802.  
  803.                         /* Stuff the character into the buffer. */
  804.  
  805.                     default:
  806.  
  807.                         SharedBuffer[Count++] = String[i];
  808.                         break;
  809.                 }
  810.  
  811.                 GotControl = FALSE;
  812.             }
  813.         }
  814.  
  815.             /* If the buffer is full, release it. */
  816.  
  817.         if(Count == 256)
  818.         {
  819.             (*SendLineLocal)(SharedBuffer,Count);
  820.  
  821.             Count = 0;
  822.         }
  823.     }
  824.  
  825.     if(Count)
  826.         (*SendLineLocal)(SharedBuffer,Count);
  827. }
  828.  
  829.     /* SerWrite(APTR Buffer,LONG Size):
  830.      *
  831.      *    Send a number of bytes across the serial line.
  832.      */
  833.  
  834. VOID __regargs
  835. SerWrite(APTR Buffer,LONG Size)
  836. {
  837.     if(Size < 0)
  838.         Size = strlen(Buffer);
  839.  
  840.     if(WriteRequest && Size)
  841.     {
  842.         STATIC UBYTE TranslateData[512];
  843.  
  844.             /* xpr wants to see the data before it is
  845.              * transferred.
  846.              */
  847.  
  848.         if(XProtocolBase && (TransferBits & XPRS_USERMON))
  849.         {
  850.             if(Size = XProtocolUserMon(XprIO,Buffer,Size,Size))
  851.             {
  852.                 if(SendTable)
  853.                 {
  854.                     struct TranslationHandle Handle;
  855.  
  856.                         /* Set up for buffer translation. */
  857.  
  858.                     TranslateSetup(&Handle,Buffer,Size,TranslateData,512,SendTable);
  859.  
  860.                         /* Full or half duplex? */
  861.  
  862.                     if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  863.                     {
  864.                             /* Process the data... */
  865.  
  866.                         while(Size = TranslateBuffer(&Handle))
  867.                         {
  868.                             WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  869.                             WriteRequest -> IOSer . io_Data        = TranslateData;
  870.                             WriteRequest -> IOSer . io_Length    = Size;
  871.  
  872.                                 /* ...and send it. */
  873.  
  874.                             DoIO(WriteRequest);
  875.  
  876.                             BytesOut += Size;
  877.                         }
  878.                     }
  879.                     else
  880.                     {
  881.                         if(Marking)
  882.                             DropMarker();
  883.  
  884.                         ClearCursor();
  885.  
  886.                         while(Size = TranslateBuffer(&Handle))
  887.                         {
  888.                             WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  889.                             WriteRequest -> IOSer . io_Data        = TranslateData;
  890.                             WriteRequest -> IOSer . io_Length    = Size;
  891.  
  892.                                 /* Process the data while it is transferred. */
  893.  
  894.                             SendIO(WriteRequest);
  895.  
  896.                             ConProcess(Buffer,Size);
  897.  
  898.                             WaitIO(WriteRequest);
  899.  
  900.                             BytesOut += Size;
  901.                         }
  902.  
  903.                         DrawCursor();
  904.                     }
  905.                 }
  906.                 else
  907.                 {
  908.                     WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  909.                     WriteRequest -> IOSer . io_Data        = Buffer;
  910.                     WriteRequest -> IOSer . io_Length    = Size;
  911.  
  912.                         /* If full duplex is enabled, send the entire
  913.                          * buffer without processing.
  914.                          */
  915.  
  916.                     if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  917.                         DoIO(WriteRequest);
  918.                     else
  919.                     {
  920.                             /* Process the data while it is transferred. */
  921.  
  922.                         SendIO(WriteRequest);
  923.  
  924.                         if(Marking)
  925.                             DropMarker();
  926.  
  927.                         ClearCursor();
  928.  
  929.                         ConProcess(Buffer,Size);
  930.  
  931.                         DrawCursor();
  932.  
  933.                         WaitIO(WriteRequest);
  934.                     }
  935.  
  936.                     BytesOut += Size;
  937.                 }
  938.             }
  939.         }
  940.         else
  941.         {
  942.             if(SendTable)
  943.             {
  944.                 struct TranslationHandle Handle;
  945.  
  946.                     /* Set up for buffer translation. */
  947.  
  948.                 TranslateSetup(&Handle,Buffer,Size,TranslateData,512,SendTable);
  949.  
  950.                     /* Full or half duplex? */
  951.  
  952.                 if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  953.                 {
  954.                         /* Process the data... */
  955.  
  956.                     while(Size = TranslateBuffer(&Handle))
  957.                     {
  958.                         WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  959.                         WriteRequest -> IOSer . io_Data        = TranslateData;
  960.                         WriteRequest -> IOSer . io_Length    = Size;
  961.  
  962.                             /* ...and send it. */
  963.  
  964.                         DoIO(WriteRequest);
  965.  
  966.                         BytesOut += Size;
  967.                     }
  968.                 }
  969.                 else
  970.                 {
  971.                     if(Marking)
  972.                         DropMarker();
  973.  
  974.                     ClearCursor();
  975.  
  976.                     while(Size = TranslateBuffer(&Handle))
  977.                     {
  978.                         WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  979.                         WriteRequest -> IOSer . io_Data        = TranslateData;
  980.                         WriteRequest -> IOSer . io_Length    = Size;
  981.  
  982.                             /* Process the data while it is transferred. */
  983.  
  984.                         SendIO(WriteRequest);
  985.  
  986.                         ConProcess(Buffer,Size);
  987.  
  988.                         WaitIO(WriteRequest);
  989.  
  990.                         BytesOut += Size;
  991.                     }
  992.  
  993.                     DrawCursor();
  994.                 }
  995.             }
  996.             else
  997.             {
  998.                 WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  999.                 WriteRequest -> IOSer . io_Data        = Buffer;
  1000.                 WriteRequest -> IOSer . io_Length    = Size;
  1001.  
  1002.                     /* If full duplex is enabled, send the entire
  1003.                      * buffer without processing.
  1004.                      */
  1005.  
  1006.                 if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  1007.                     DoIO(WriteRequest);
  1008.                 else
  1009.                 {
  1010.                         /* Process the data while it is transferred. */
  1011.  
  1012.                     SendIO(WriteRequest);
  1013.  
  1014.                     if(Marking)
  1015.                         DropMarker();
  1016.  
  1017.                     ClearCursor();
  1018.  
  1019.                     ConProcess(Buffer,Size);
  1020.  
  1021.                     DrawCursor();
  1022.  
  1023.                     WaitIO(WriteRequest);
  1024.                 }
  1025.  
  1026.                 BytesOut += Size;
  1027.             }
  1028.         }
  1029.     }
  1030. }
  1031.  
  1032.     /* RestartSerial():
  1033.      *
  1034.      *    Restart read/write activity on the serial line.
  1035.      */
  1036.  
  1037. VOID
  1038. RestartSerial()
  1039. {
  1040.     if(ReadRequest)
  1041.     {
  1042.         ReadRequest -> IOSer . io_Command    = CMD_READ;
  1043.         ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1044.         ReadRequest -> IOSer . io_Length     = 1;
  1045.  
  1046.         ClrSignal(SIG_SERIAL);
  1047.  
  1048.         SendIO(ReadRequest);
  1049.     }
  1050. }
  1051.  
  1052.     /* ClearSerial():
  1053.      *
  1054.      *    Terminate all read/write activity on the serial line.
  1055.      */
  1056.  
  1057. VOID
  1058. ClearSerial()
  1059. {
  1060.     if(ReadRequest)
  1061.     {
  1062.         if(!CheckIO(ReadRequest))
  1063.             AbortIO(ReadRequest);
  1064.  
  1065.         WaitIO(ReadRequest);
  1066.     }
  1067.  
  1068.     if(WriteRequest)
  1069.     {
  1070.         WriteRequest -> IOSer . io_Command = CMD_FLUSH;
  1071.  
  1072.         DoIO(WriteRequest);
  1073.  
  1074.         WriteRequest -> IOSer . io_Command = CMD_CLEAR;
  1075.  
  1076.         DoIO(WriteRequest);
  1077.     }
  1078. }
  1079.  
  1080.     /* DropDTR():
  1081.      *
  1082.      *    Drop the data terminal ready signal (i.e. close, wait a bit
  1083.      *    and then reopen the serial drive).
  1084.      */
  1085.  
  1086. BYTE
  1087. DropDTR()
  1088. {
  1089.         /* Finish all serial read activity. */
  1090.  
  1091.     ClearSerial();
  1092.  
  1093.         /* Do we have any channels to work with? */
  1094.  
  1095.     if(ReadRequest && WriteRequest)
  1096.     {
  1097.             /* Close the device. */
  1098.  
  1099.         CloseDevice(ReadRequest);
  1100.  
  1101.             /* Wait a bit. */
  1102.  
  1103.         WaitTime(1,0);
  1104.  
  1105.             /* Set up the original configuration data. */
  1106.  
  1107.         SetFlags(ReadRequest);
  1108.  
  1109.         ReadRequest -> io_RBufLen = Config -> SerialConfig -> SerialBufferSize;
  1110.  
  1111.             /* Reopen the driver. */
  1112.  
  1113.         if(!OpenDevice(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,ReadRequest,0))
  1114.         {
  1115.             struct MsgPort *WritePort = WriteRequest -> IOSer . io_Message . mn_ReplyPort;
  1116.  
  1117.                 /* Fill in the rest. */
  1118.  
  1119.             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  1120.  
  1121.             WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  1122.  
  1123.             WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  1124.  
  1125.             SetFlags(WriteRequest);
  1126.  
  1127.             DoIO(WriteRequest);
  1128.  
  1129.                 /* Restart read activity. */
  1130.  
  1131.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  1132.             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1133.             ReadRequest -> IOSer . io_Length    = 1;
  1134.  
  1135.             ClrSignal(SIG_SERIAL);
  1136.  
  1137.             SendIO(ReadRequest);
  1138.  
  1139.             return(TRUE);
  1140.         }
  1141.         else
  1142.             DeleteSerial();
  1143.     }
  1144.     else
  1145.     {
  1146.         DeleteSerial();
  1147.  
  1148.         return(TRUE);
  1149.     }
  1150.  
  1151.     return(FALSE);
  1152. }
  1153.  
  1154.     /* DeleteSerial():
  1155.      *
  1156.      *    Close the serial device and release all associated
  1157.      *    resources.
  1158.      */
  1159.  
  1160. VOID
  1161. DeleteSerial()
  1162. {
  1163.     BYTE Closed = FALSE;
  1164.  
  1165.     if(ReadRequest)
  1166.     {
  1167.         if(ReadRequest -> IOSer . io_Device)
  1168.         {
  1169.             if(!Config -> SerialConfig -> Shared)
  1170.             {
  1171.                 ReadRequest -> IOSer . io_Command = CMD_RESET;
  1172.  
  1173.                 DoIO(ReadRequest);
  1174.             }
  1175.  
  1176.             CloseDevice(ReadRequest);
  1177.  
  1178.             Closed = TRUE;
  1179.         }
  1180.  
  1181.         DeleteIORequest(ReadRequest);
  1182.  
  1183.         ReadRequest = NULL;
  1184.     }
  1185.  
  1186.     if(WriteRequest)
  1187.     {
  1188.         if(WriteRequest -> IOSer . io_Device && !Closed)
  1189.         {
  1190.             if(!Config -> SerialConfig -> Shared && ReadRequest)
  1191.             {
  1192.                 ReadRequest -> IOSer . io_Command = CMD_RESET;
  1193.  
  1194.                 DoIO(ReadRequest);
  1195.             }
  1196.  
  1197.             CloseDevice(WriteRequest);
  1198.         }
  1199.  
  1200.         if(WriteRequest -> IOSer . io_Message . mn_ReplyPort)
  1201.             DeleteMsgPort(WriteRequest -> IOSer . io_Message . mn_ReplyPort);
  1202.  
  1203.         DeleteIORequest(WriteRequest);
  1204.  
  1205.         WriteRequest = NULL;
  1206.     }
  1207.  
  1208.     if(ReadPort)
  1209.     {
  1210.         DeleteMsgPort(ReadPort);
  1211.  
  1212.         ReadPort = NULL;
  1213.     }
  1214.  
  1215.     if(ReadBuffer)
  1216.     {
  1217.         FreeVec(ReadBuffer);
  1218.  
  1219.         ReadBuffer = NULL;
  1220.     }
  1221.  
  1222.     if(HostReadBuffer)
  1223.     {
  1224.         FreeVec(HostReadBuffer);
  1225.  
  1226.         HostReadBuffer = NULL;
  1227.     }
  1228.  
  1229.     if(StripBuffer)
  1230.     {
  1231.         FreeVec(StripBuffer);
  1232.  
  1233.         StripBuffer = NULL;
  1234.     }
  1235.  
  1236.     if(OwnDevUnitBase && SerialDevice[0] && UnitNumber != -1)
  1237.     {
  1238.         FreeDevUnit(SerialDevice,UnitNumber);
  1239.  
  1240.         SerialDevice[0] = 0;
  1241.  
  1242.         UnitNumber = -1;
  1243.     }
  1244. }
  1245.  
  1246.     /* GetSerialError(LONG Error,BYTE *Reset):
  1247.      *
  1248.      *    Return an error message for each possible serial device error.
  1249.      */
  1250.  
  1251. STRPTR
  1252. GetSerialError(LONG Error,BYTE *Reset)
  1253. {
  1254.     if(Reset)
  1255.         *Reset = FALSE;
  1256.  
  1257.     switch(Error)
  1258.     {
  1259.         case IOERR_BADLENGTH:
  1260.         case IOERR_BADADDRESS:
  1261.         case IOERR_SELFTEST:
  1262.         case IOERR_OPENFAIL:
  1263.  
  1264.             return(LocaleString(MSG_SERIAL_OPENFAILURE_TXT));
  1265.  
  1266.         case SerErr_DevBusy:
  1267.  
  1268.             return(LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT));
  1269.  
  1270.         case SerErr_BaudMismatch:
  1271.  
  1272.             if(Reset)
  1273.                 *Reset = TRUE;
  1274.  
  1275.             return(LocaleString(MSG_SERIAL_ERROR_BAUDMISMATCH_TXT));
  1276.  
  1277.         case SerErr_BufErr:
  1278.  
  1279.             if(Reset)
  1280.                 *Reset = TRUE;
  1281.  
  1282.             return(LocaleString(MSG_SERIAL_ERROR_BUFERR_TXT));
  1283.  
  1284.         case SerErr_InvParam:
  1285.  
  1286.             if(Reset)
  1287.                 *Reset = TRUE;
  1288.  
  1289.             return(LocaleString(MSG_SERIAL_ERROR_INVPARAM_TXT));
  1290.  
  1291.         case SerErr_LineErr:
  1292.  
  1293.             return(LocaleString(MSG_SERIAL_ERROR_LINEERR_TXT));
  1294.  
  1295.         case SerErr_ParityErr:
  1296.  
  1297.             if(Reset)
  1298.                 *Reset = TRUE;
  1299.  
  1300.             return(LocaleString(MSG_SERIAL_ERROR_PARITYERR_TXT));
  1301.  
  1302.         case SerErr_TimerErr:
  1303.  
  1304.             return(LocaleString(MSG_SERIAL_ERROR_TIMERERR_TXT));
  1305.  
  1306.         case SerErr_BufOverflow:
  1307.  
  1308.             if(Reset)
  1309.                 *Reset = TRUE;
  1310.  
  1311.             return(LocaleString(MSG_SERIAL_ERROR_BUFOVERFLOW_TXT));
  1312.  
  1313.         case SerErr_NoDSR:
  1314.  
  1315.             return(LocaleString(MSG_SERIAL_ERROR_NODSR_TXT));
  1316.  
  1317.     /*    case SerErr_UnitBusy:    */
  1318.         case IOERR_UNITBUSY:
  1319.         case 16:
  1320.  
  1321.             return(LocaleString(MSG_SERIAL_ERROR_UNIT_BUSY_TXT));
  1322.  
  1323.         default:
  1324.  
  1325.             return(NULL);
  1326.     }
  1327. }
  1328.  
  1329.     /* CreateSerial():
  1330.      *
  1331.      *    Create handles for the serial device and open it.
  1332.      */
  1333.  
  1334. STRPTR
  1335. CreateSerial()
  1336. {
  1337.     struct MsgPort *WritePort;
  1338.  
  1339.         /* If OwnDevUnit.library is available, try to lock
  1340.          * the serial driver.
  1341.          */
  1342.  
  1343. Start:    if(OwnDevUnitBase)
  1344.     {
  1345.         STRPTR Error;
  1346.  
  1347.             /* Attempt to lock the device unit... */
  1348.  
  1349.         if(Error = AttemptDevUnit(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,TermIDString,NULL))
  1350.         {
  1351.                 /* Check for error type if any. */
  1352.  
  1353.             if(!Strnicmp(Error,ODUERR_LEADCHAR,1))
  1354.                 SPrintf(SharedBuffer,LocaleString(MSG_SERIAL_ERROR_ACCESSING_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,&Error[1]);
  1355.             else
  1356.                 SPrintf(SharedBuffer,LocaleString(MSG_SERIAL_DEVICE_IN_USE_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,Error);
  1357.  
  1358.             SerialDevice[0] = 0;
  1359.  
  1360.             UnitNumber = -1;
  1361.  
  1362.             return(SharedBuffer);
  1363.         }
  1364.         else
  1365.         {
  1366.             strcpy(SerialDevice,Config -> SerialConfig -> SerialDevice);
  1367.  
  1368.             UnitNumber = Config -> SerialConfig -> UnitNumber;
  1369.         }
  1370.     }
  1371.  
  1372.     if(ReadBuffer = AllocVec(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
  1373.     {
  1374.         if(StripBuffer = AllocVec(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
  1375.         {
  1376.             if(XProtocolBase && (TransferBits & XPRS_HOSTNOWAIT))
  1377.                 HostReadBuffer = AllocVec(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  1378.             else
  1379.                 HostReadBuffer = NULL;
  1380.  
  1381.             if(ReadPort = (struct MsgPort *)CreateMsgPort())
  1382.             {
  1383.                 if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
  1384.                 {
  1385.                     LONG Error;
  1386.  
  1387.                     SetFlags(ReadRequest);
  1388.  
  1389.                     ReadRequest -> io_RBufLen = Config -> SerialConfig -> SerialBufferSize;
  1390.  
  1391.                     if(!(Error = OpenDevice(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,ReadRequest,0)))
  1392.                     {
  1393.                         if(WritePort = (struct MsgPort *)CreateMsgPort())
  1394.                         {
  1395.                             if(WriteRequest = (struct IOExtSer *)CreateIORequest(WritePort,sizeof(struct IOExtSer)))
  1396.                             {
  1397.                                 CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  1398.  
  1399.                                 WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  1400.  
  1401.                                 WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  1402.  
  1403.                                 SetFlags(WriteRequest);
  1404.  
  1405.                                 DoIO(WriteRequest);
  1406.  
  1407.                                 /* If RTS/CTS (7 wire handshaking) is
  1408.                                  * selected, have a look at the DSR
  1409.                                  * line to see whether the modem
  1410.                                  * connected is willing to support
  1411.                                  * this handshaking mode.
  1412.                                  */
  1413.  
  1414.                                 if(Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_RTSCTS_DSR)
  1415.                                 {
  1416. Retry:                                    WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1417.  
  1418.                                     DoIO(WriteRequest);
  1419.  
  1420.                                         /* If the line happens to
  1421.                                          * be high, there is no
  1422.                                          * DSR signal present.
  1423.                                          */
  1424.  
  1425.                                     if(WriteRequest -> io_Status & CIAF_COMDSR)
  1426.                                     {
  1427.                                         if(MyEasyRequest(Window,LocaleString(MSG_SERIAL_NO_DSR_SIGNAL_TXT),LocaleString(MSG_SERIAL_RETRY_CANCEL_TXT)))
  1428.                                             goto Retry;
  1429.                                         else
  1430.                                         {
  1431.                                             DeleteSerial();
  1432.  
  1433.                                             Config -> SerialConfig -> HandshakingProtocol = HANDSHAKING_NONE;
  1434.  
  1435.                                             SerialMessage = LocaleString(MSG_SERIAL_NO_DSR_SIGNAL_HANDSHAKING_DISABLED_TXT);
  1436.  
  1437.                                             goto Start;
  1438.                                         }
  1439.                                     }
  1440.                                 }
  1441.  
  1442.                                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  1443.                                 ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1444.                                 ReadRequest -> IOSer . io_Length    = 1;
  1445.  
  1446.                                 ClrSignal(SIG_SERIAL);
  1447.  
  1448.                                 SendIO(ReadRequest);
  1449.  
  1450.                                 return(NULL);
  1451.                             }
  1452.                         }
  1453.                         else
  1454.                         {
  1455.                             SerialMessage = NULL;
  1456.  
  1457.                             DeleteSerial();
  1458.  
  1459.                             return(LocaleString(MSG_SERIAL_FAILED_TO_CREATE_WRITE_PORT_TXT));
  1460.                         }
  1461.                     }
  1462.                     else
  1463.                     {
  1464.                         STRPTR String;
  1465.  
  1466.                         ReadRequest -> IOSer . io_Device = NULL;
  1467.  
  1468.                         DeleteSerial();
  1469.  
  1470.                         SerialMessage = NULL;
  1471.  
  1472.                         if(!(String = GetSerialError(Error,NULL)))
  1473.                             String = LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT);
  1474.  
  1475.                         SPrintf(SharedBuffer,String,Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber);
  1476.  
  1477.                         return(SharedBuffer);
  1478.                     }
  1479.                 }
  1480.             }
  1481.             else
  1482.             {
  1483.                 SerialMessage = NULL;
  1484.  
  1485.                 DeleteSerial();
  1486.  
  1487.                 return(LocaleString(MSG_SERIAL_FAILED_TO_CREATE_READ_PORT_TXT));
  1488.             }
  1489.         }
  1490.     }
  1491.  
  1492.     SerialMessage = NULL;
  1493.  
  1494.     DeleteSerial();
  1495.  
  1496.     return(LocaleString(MSG_SERIAL_NOT_ENOUGH_MEMORY_TXT));
  1497. }
  1498.  
  1499.     /* ReconfigureSerial(struct Window *Window,struct SerialSettings *SerialConfig):
  1500.      *
  1501.      *    Reconfigure the serial driver according to the new
  1502.      *    serial settings.
  1503.      */
  1504.  
  1505. BYTE
  1506. ReconfigureSerial(struct Window *Window,struct SerialSettings *SerialConfig)
  1507. {
  1508.     BYTE    Success    = RECONFIGURE_NOCHANGE,
  1509.         IsNew;
  1510.  
  1511.         /* Are new settings to be installed or have they already
  1512.          * been copied to the correct locations?
  1513.          */
  1514.  
  1515.     if(SerialConfig)
  1516.     {
  1517.         if(memcmp(Config -> SerialConfig,SerialConfig,sizeof(struct SerialSettings)))
  1518.             IsNew = TRUE;
  1519.         else
  1520.             IsNew = FALSE;
  1521.     }
  1522.     else
  1523.     {
  1524.         if(memcmp(Config -> SerialConfig,PrivateConfig -> SerialConfig,sizeof(struct SerialSettings)))
  1525.             IsNew = TRUE;
  1526.         else
  1527.             IsNew = FALSE;
  1528.     }
  1529.  
  1530.         /* Any changes in the serial configuration area? */
  1531.  
  1532.     if(IsNew)
  1533.     {
  1534.         BYTE SameDevice = TRUE;
  1535.  
  1536.             /* Any new data to swap in? */
  1537.  
  1538.         if(SerialConfig)
  1539.         {
  1540.                 /* Store the previous settings. */
  1541.  
  1542.             SaveConfig(Config,PrivateConfig);
  1543.  
  1544.                 /* Install the new settings. */
  1545.  
  1546.             memcpy(Config -> SerialConfig,SerialConfig,sizeof(struct SerialSettings));
  1547.         }
  1548.  
  1549.             /* Any device name or unit number change? */
  1550.  
  1551.         if(strcmp(PrivateConfig -> SerialConfig -> SerialDevice,Config -> SerialConfig -> SerialDevice) || PrivateConfig -> SerialConfig -> UnitNumber != Config -> SerialConfig -> UnitNumber)
  1552.             SameDevice = FALSE;
  1553.         else
  1554.         {
  1555.                 /* Handshaking mode changed to RTS/CTS protocol? */
  1556.  
  1557.             if((PrivateConfig -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE && Config -> SerialConfig -> HandshakingProtocol != HANDSHAKING_NONE) || (PrivateConfig -> SerialConfig -> HandshakingProtocol != HANDSHAKING_NONE && Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE))
  1558.                 SameDevice = FALSE;
  1559.         }
  1560.  
  1561.             /* Stop any IO activity. */
  1562.  
  1563.         if(ReadRequest)
  1564.             ClearSerial();
  1565.         else
  1566.             SameDevice = FALSE;
  1567.  
  1568.             /* No dramatic changes? Simply change the parameters. */
  1569.  
  1570.         if(SameDevice)
  1571.         {
  1572.             LONG Error;
  1573.  
  1574.             if(PrivateConfig -> SerialConfig -> SerialBufferSize != Config -> SerialConfig -> SerialBufferSize)
  1575.             {
  1576.                 STRPTR NewReadBuffer;
  1577.  
  1578.                 if(NewReadBuffer = AllocVec(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
  1579.                 {
  1580.                     STRPTR NewStripBuffer;
  1581.  
  1582.                     if(NewStripBuffer = AllocVec(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
  1583.                     {
  1584.                         FreeVec(ReadBuffer);
  1585.                         FreeVec(StripBuffer);
  1586.  
  1587.                         ReadBuffer    = NewReadBuffer;
  1588.                         StripBuffer    = NewStripBuffer;
  1589.                     }
  1590.                     else
  1591.                     {
  1592.                         FreeVec(NewReadBuffer);
  1593.  
  1594.                         Config -> SerialConfig -> SerialBufferSize = PrivateConfig -> SerialConfig -> SerialBufferSize;
  1595.                     }
  1596.                 }
  1597.                 else
  1598.                     Config -> SerialConfig -> SerialBufferSize = PrivateConfig -> SerialConfig -> SerialBufferSize;
  1599.             }
  1600.  
  1601.                 /* Use new parameters... */
  1602.  
  1603.             SetFlags(WriteRequest);
  1604.             SetFlags(ReadRequest);
  1605.  
  1606.                 /* ...and set them. */
  1607.  
  1608.             WriteRequest -> IOSer . io_Command    = SDCMD_SETPARAMS;
  1609.             ReadRequest -> IOSer . io_Command    = SDCMD_SETPARAMS;
  1610.  
  1611.             if(!(Error = DoIO(WriteRequest)))
  1612.                 Error = DoIO(ReadRequest);
  1613.  
  1614.                 /* Trouble? */
  1615.  
  1616.             if(Error)
  1617.             {
  1618.                 STRPTR    String;
  1619.                 BYTE    Reset;
  1620.  
  1621.                     /* Query the error message. */
  1622.  
  1623.                 if(!(String = GetSerialError(Error,&Reset)))
  1624.                     String = LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT);
  1625.  
  1626.                     /* Build the device name/unit number string. */
  1627.  
  1628.                 SPrintf(SharedBuffer,String,Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber);
  1629.  
  1630.                     /* Display the error requester. */
  1631.  
  1632.                 BlockWindow(Window);
  1633.  
  1634.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SharedBuffer);
  1635.  
  1636.                 ReleaseWindow(Window);
  1637.  
  1638.                     /* Is a serial driver reset required? */
  1639.  
  1640.                 if(Reset)
  1641.                 {
  1642.                         /* Execute the reset command. */
  1643.  
  1644.                     WriteRequest -> IOSer . io_Command = CMD_RESET;
  1645.  
  1646.                     DoIO(WriteRequest);
  1647.  
  1648.                         /* Copy the serial driver settings
  1649.                          * to the global configuration.
  1650.                          */
  1651.  
  1652.                     GetFlags(Config,WriteRequest);
  1653.  
  1654.                         /* Also set the read request driver
  1655.                          * flags.
  1656.                          */
  1657.  
  1658.                     SetFlags(ReadRequest);
  1659.  
  1660.                     ReadRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  1661.  
  1662.                     DoIO(ReadRequest);
  1663.                 }
  1664.             }
  1665.  
  1666.                 /* Restart read request. */
  1667.  
  1668.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  1669.             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1670.             ReadRequest -> IOSer . io_Length    = 1;
  1671.  
  1672.             ClrSignal(SIG_SERIAL);
  1673.  
  1674.             SendIO(ReadRequest);
  1675.         }
  1676.         else
  1677.         {
  1678.             STRPTR Error;
  1679.  
  1680.                 /* Shut down the serial driver. */
  1681.  
  1682.             DeleteSerial();
  1683.  
  1684.                 /* Reinitialize the serial driver. */
  1685.  
  1686.             if(!(Error = CreateSerial()))
  1687.             {
  1688.                     /* Free the work buffer. */
  1689.  
  1690.                 if(StripBuffer)
  1691.                     FreeVec(StripBuffer);
  1692.  
  1693.                     /* Try to allocate a new serial data work buffer. */
  1694.  
  1695.                 if(!(StripBuffer = (STRPTR)AllocVec(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY)))
  1696.                     Error = LocaleString(MSG_GLOBAL_NO_AUX_BUFFERS_TXT);
  1697.             }
  1698.  
  1699.                 /* Trouble? */
  1700.  
  1701.             if(Error)
  1702.             {
  1703.                     /* Display the error requester. */
  1704.  
  1705.                 BlockWindow(Window);
  1706.  
  1707.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  1708.  
  1709.                     /* Clean up the mess :-( */
  1710.  
  1711.                 DeleteSerial();
  1712.  
  1713.                 ReleaseWindow(Window);
  1714.  
  1715.                 Success = RECONFIGURE_FAILURE;
  1716.             }
  1717.             else
  1718.             {
  1719.                     /* Are we to display an error message? */
  1720.  
  1721.                 if(SerialMessage)
  1722.                 {
  1723.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  1724.  
  1725.                     SerialMessage = NULL;
  1726.                 }
  1727.             }
  1728.         }
  1729.     }
  1730.  
  1731.     return(Success);
  1732. }
  1733.  
  1734.     /* ReopenSerial():
  1735.      *
  1736.      *    Reopen the serial driver.
  1737.      */
  1738.  
  1739. VOID
  1740. ReopenSerial()
  1741. {
  1742.     BYTE    SerialClosed = TRUE;
  1743.     STRPTR    Error;
  1744.  
  1745.     do
  1746.     {
  1747.         if(Error = CreateSerial())
  1748.         {
  1749.             DeleteSerial();
  1750.  
  1751.             switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_RETRY_IGNORE_QUIT_TXT),Error))
  1752.             {
  1753.                 case 2:    SerialClosed = FALSE;
  1754.                     break;
  1755.  
  1756.                 case 0:    MainTerminated = TRUE;
  1757.                     break;
  1758.             }
  1759.         }
  1760.         else
  1761.         {
  1762.             SerialClosed = FALSE;
  1763.  
  1764.             if(SerialMessage)
  1765.             {
  1766.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  1767.  
  1768.                 SerialMessage = NULL;
  1769.             }
  1770.         }
  1771.     }
  1772.     while(SerialClosed);
  1773. }
  1774.  
  1775.     /* HandleSerial():
  1776.      *
  1777.      *    Handle the data coming in from the serial line.
  1778.      */
  1779.  
  1780. BYTE
  1781. HandleSerial()
  1782. {
  1783.     BYTE MoreData = FALSE;
  1784.  
  1785.     if(ReadPort && !ReleaseSerial && Status != STATUS_HOLDING)
  1786.     {
  1787.         if(HostReadBuffer)
  1788.         {
  1789.             LONG Length = XProtocolHostMon(XprIO,HostReadBuffer,0,Config -> SerialConfig -> SerialBufferSize);
  1790.  
  1791.             if(Length)
  1792.             {
  1793.                 if(Marking)
  1794.                     DropMarker();
  1795.  
  1796.                 ClearCursor();
  1797.  
  1798.                 ConProcess(HostReadBuffer,Length);
  1799.  
  1800.                 if(Status == STATUS_HOLDING)
  1801.                 {
  1802.                     DrawCursor();
  1803.  
  1804.                     return(FALSE);
  1805.                 }
  1806.             }
  1807.  
  1808.             MoreData = TRUE;
  1809.         }
  1810.  
  1811.         if(DataHold)
  1812.         {
  1813.             if(DataSize > 0)
  1814.             {
  1815.                 register STRPTR    Data    = DataHold;
  1816.                 register LONG    Size    = DataSize;
  1817.  
  1818.                 DataHold = NULL;
  1819.                 DataSize = 0;
  1820.  
  1821.                 if(Marking)
  1822.                     DropMarker();
  1823.  
  1824.                 ClearCursor();
  1825.  
  1826.                 (* ConTransfer)(Data,Size);
  1827.  
  1828.                 DrawCursor();
  1829.  
  1830.                 MoreData = TRUE;
  1831.             }
  1832.             else
  1833.                 DataHold = NULL;
  1834.  
  1835.             RestartSerial();
  1836.  
  1837.             return(MoreData);
  1838.         }
  1839.  
  1840.             /* Any news? */
  1841.  
  1842.         if(CheckIO(ReadRequest))
  1843.         {
  1844.             MoreData = TRUE;
  1845.  
  1846.             if(!WaitIO(ReadRequest))
  1847.             {
  1848.                 if(Marking)
  1849.                     DropMarker();
  1850.  
  1851.                 ClearCursor();
  1852.  
  1853.                 BytesIn++;
  1854.  
  1855.                 (* ConTransfer)(ReadBuffer,1);
  1856.  
  1857.                 if(Status != STATUS_HOLDING && !DataHold)
  1858.                 {
  1859.                     ULONG Length;
  1860.  
  1861.                         /* Check how many bytes are still in
  1862.                          * the serial buffer.
  1863.                          */
  1864.  
  1865.                     WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1866.  
  1867.                     DoIO(WriteRequest);
  1868.  
  1869.                     if(Length = WriteRequest -> IOSer . io_Actual)
  1870.                     {
  1871.                         ULONG Max = Config -> SerialConfig -> SerialBufferSize;
  1872.  
  1873.                         if(Max > Config -> SerialConfig -> Quantum)
  1874.                             Max = Config -> SerialConfig -> Quantum;
  1875.  
  1876.                         if(Length > Max)
  1877.                             Length = Max;
  1878.  
  1879.                         ReadRequest -> IOSer . io_Command    = CMD_READ;
  1880.                         ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1881.                         ReadRequest -> IOSer . io_Length    = Length;
  1882.  
  1883.                         if(!DoIO(ReadRequest))
  1884.                         {
  1885.                             BytesIn += Length;
  1886.  
  1887.                             (* ConTransfer)(ReadBuffer,Length);
  1888.                         }
  1889.                     }
  1890.                 }
  1891.  
  1892.                 DrawCursor();
  1893.             }
  1894.  
  1895.             if(DataHold)
  1896.                 ClrSignal(SIG_SERIAL);
  1897.             else
  1898.                 RestartSerial();
  1899.         }
  1900.     }
  1901.  
  1902.     return(MoreData);
  1903. }
  1904.